home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
CONTAINER
/
Container.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-22
|
5KB
|
257 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Container.h"
#include "Class.h"
#include "Error.h"
#include "String.h"
//---- initialization of exported variables -------------------------------------
char *cWarningActiveIterator= "there are active iterators";
char *cWarningNullArgument = "argument is a null pointer";
//---- Container -----------------------------------------------------------
NewAbstractMetaImpl0(Container,Object);
Container *Container::currentContainer;
Container::Container()
{
size= 0;
nDeleted= 0;
iterCount= 0;
anchor.Init();
}
Container::~Container()
{
if ( HasIterator() )
ForIteratorsDoAndRemove(&Iterator::AboutToDie);
}
void Container::InitNew()
{
size= 0;
nDeleted= 0;
iterCount= 0;
anchor.Init();
}
int Container::Capacity()
{
return size;
}
bool Container::assertclass(Class *cl)
{
register Object *op;
Iter next(this);
bool error= FALSE;
if ( cl == 0 ) {
Error("assertclass", "class == 0");
return TRUE;
}
for ( int i= 0; op= next(); i++ )
if ( ! op->IsA()->isKindOf(cl) ) {
Error("assertclass", "element %d is not instance of class %s (%s)", i,
cl->Name(), op->ClassName());
error= TRUE;
}
return error;
}
void Container::InspectorId(char *b, int sz)
{
static char cb[512];
Object *op= AnyElement();
if (op)
sprintf(cb, "[%d] <%s>", Size(), op->ClassName());
else
sprintf(cb, "[%d]", Size());
strn0cpy(b, cb, sz-1);
}
//---- container comparison
bool Container::IsEqual(Object *col)
{
// ?? this code is strange
if ( IsA() != col->IsA() )
return FALSE;
Iter next1(this), next2((Container *)col);
register Object *op1, *op2;
for (;;) {
op1= next1();
op2= next2();
if ( op1 == 0 && op2 == 0 )
return TRUE;
if ( op1 == 0 || op2 == 0 )
break;
if ( ! op1->IsEqual(op2) )
break;
}
return FALSE;
}
u_long Container::Hash()
{
Iter next(this);
register Object *op;
register unsigned long s= 0;
while ( op= next() )
s^= op->Hash();
return s;
}
//---- access
Iterator *Container::MakeIterator(bool)
{
AbstractMethod("MakeIterator");
return 0;
}
Object *Container::AnyElement()
{
Iter next(this);
return next();
}
Object *Container::Find(Object *anOp)
{
register Object *op;
if ( anOp == 0 )
return 0;
Iter next(this);
while ( op= next() )
if ( op->IsEqual(anOp) )
return op;
return 0;
}
Object *Container::FindPtr(Object *anOp)
{
register Object *op;
if ( anOp == 0 )
return 0;
Iter next(this);
while ( op= next() )
if ( op == anOp )
return op;
return 0;
}
int Container::OccurrencesOf(Object *anOp)
{
register Object *op;
register int n= 0;
if ( anOp == 0 ) {
Warning("OccurrencesOf", cWarningNullArgument);
return 0;
}
Iter next(this);
while (op = next())
if ( op->IsEqual(anOp) )
n++;
return n;
}
int Container::OccurrencesOfPtr(Object *anOp)
{
register Object *op;
register int n= 0;
if ( anOp == 0 )
return FALSE;
Iter next(this);
while ( op= next() )
if ( op == anOp )
n++;
return n;
}
//---- object i/o
OStream &Container::PrintOn(OStream &os)
{
Object::PrintOn(os);
os << size SP;
return os;
}
IStream &Container::ReadFrom(IStream &is)
{
Object::ReadFrom(is);
is >> size;
anchor.Init();
return is;
}
//---- robust iterators
void Container::IteratorStart(Iterator *it)
{
if ( it ) {
iterCount++;
it->ChainIn(&anchor);
} else
Warning("IteratorStarts", cWarningNullArgument);
}
void Container::IteratorTerminate(Iterator *it)
{
if ( it ) {
iterCount--;
it->ChainOut();
if ( iterCount < 0 )
Error("IteratorTerminate", "iterCount < 0");
if ( HasDeletedObjects() && iterCount <= 0 )
RemoveDeleted();
} else
Warning("IteratorTerminate", cWarningNullArgument);
}
void Container::ForIteratorsDoAndRemove(IteratorMethod method, void *arg)
{
register Iterator *it, *jt;
it= anchor.next;
while ( it != &anchor ) {
jt= it;
it= it->next;
(jt->*method)(arg);
jt->ChainOut();
}
}
void Container::ForIteratorsDo(IteratorMethod method, void *arg)
{
register Iterator *it;
it= anchor.next;
while ( it != &anchor ) {
(it->*method)(arg);
it= it->next;
}
}
//---- robust iterators - Deleted Object approach (old style) ----
void Container::RemoveDeleted()
{
// hook
}